\documentclass[a4paper,10pt]{report}
\usepackage[top=1.5cm, bottom=1.5cm, left=2cm, right=2cm]{geometry}

\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc} % Use 8-bit encoding that has 256 glyphs
\usepackage{microtype} % Slightly tweak font spacing for aesthetics

\usepackage{hyperref}
\hypersetup{
  bookmarks=true,         % show bookmarks bar?
  unicode=false,          % non-Latin characters in Acrobat’s bookmarks
  pdfnewwindow=true,      % links in new window
  colorlinks=true,       % false: boxed links; true: colored links
  linkcolor=black,        % color of internal links (change box color with linkbordercolor)
  citecolor=magenta,        % color of links to bibliography
  filecolor=magenta,      % color of file links
  urlcolor=[rgb]{0,0,0.5}           % color of external links
}

\usepackage{multicol}
\usepackage{array}
\usepackage{lastpage}

\usepackage{fancyhdr} % Headers and footers
\pagestyle{fancy} % All pages have headers and footers
\fancyhead{} % Blank out the default header
\fancyfoot{} % Blank out the default footer
\fancyfoot[R]{\thepage/\pageref{LastPage}} % Custom footer text
\renewcommand{\headrulewidth}{0pt}

\setlength{\parindent}{0cm}
\usepackage{listings}
%\usepackage{pdfpages}
\usepackage{graphicx}
\graphicspath{ {./img/} }

\usepackage{minted} % coloration syntaxique

\usepackage{listingsutf8}
\lstdefinestyle{ShellStyle}{
  language=bash,
  breaklines=true,
  basicstyle=\footnotesize\ttfamily\color{black},
  % numbers=left,
  % numberstyle=\small,
  % numbersep=3pt,
  frame=tb,
  % columns=fullflexible,
  backgroundcolor=\color{yellow!20},
  linewidth=0.95\linewidth,
  xleftmargin=0.05\linewidth
}

\setcounter{tocdepth}{4}
%----------------------------------------------------------------------------------------

\title{\textbf{Correction du partiel de C++ de 2013}}

\begin{document}

\maketitle{}

\thispagestyle{fancy} % All pages have headers and footers

%----------------------------------------------------------------------------------------

\section*{Fonctions et instructions}
\addcontentsline{toc}{section}{Fonctions et instructions}

\subsection*{Question 1}
\addcontentsline{toc}{subsection}{Question 1}

Voici le programme de test utilisé auquel se référer pour les numéros de ligne :
\begin{minted}[linenos=true,frame=single,fontsize=\scriptsize]{c++}
int fct(int); // fonction I
int fct(double); // fonction II
void fct(int, double); // fonction III
void fct(double, int); // fonction IV

int n, p;
double x, y, z;
char c, d;

int main(void) {

    fct(n);
    fct(x);
    fct(n,x);
    fct(x,n);

    fct(c);
    fct(c,d);
    fct(n,c);
    fct(n,z);

    fct(z,z,z);

    return 0;
}

int fct(int i) {
  // ...  
  return ...;
}

int fct(double d) {
  // ...  
  return ...;
}

void fct(int i, double d) {
  // ...
}

void fct(double d, int i) {
  // ...
}
\end{minted}


a. \texttt{fct(n)} $\rightarrow$ correcte, appel à la fonction I\\

b. \texttt{fct(x)} $\rightarrow$ correcte, appel à la fonction II\\

c. \texttt{fct(n, x)} $\rightarrow$ correcte, appel à la fonction III\\

d. \texttt{fct(x, n)} $\rightarrow$ correcte, appel à la fonction IV\\

e. \texttt{fct(c)} $\rightarrow$ correcte. Le type \texttt{char} est un entier signé sur 8 bits ([-256,255]), le compilateur va effectuer un cast automatique de \texttt{char} vers \texttt{int}. La fonction appelée est donc la fonction I.\\

f. \texttt{fct(c,d)} $\rightarrow$ incorrecte. Le compilateur ne sait pas quoi faire, aucun des deux arguments ne correspond à un des deux prototypes de fonctions à deux arguements.
\begin{lstlisting}[style=ShellStyle]
test.cpp:18:12: error: call of overloaded 'fct(char&, char&)' is ambiguous
     fct(c,d);
            ^
test.cpp:18:12: note: candidates are:
test.cpp:3:6: note: void fct(int, double)
 void fct(int, double); // fonction III
      ^
test.cpp:4:6: note: void fct(double, int)
 void fct(double, int); // fonction IV
      ^
\end{lstlisting}
Dans ce cas-là, l'utilisation d'un cast explicite est requis pour désambiguiser la situation. Par exemple, pour désigner la fonction III :
\begin{minted}[linenos=false,frame=none,fontsize=\scriptsize]{c++}
  fct((int)c, (double)d);
\end{minted}

g. \texttt{fct(n,c)} $\rightarrow$ incorrecte. Le compilateur là aussi ne sait pas quoi faire bien que le premier paramètre soit de type \texttt{int}.
\begin{lstlisting}[style=ShellStyle]
test.cpp:19:12: error: call of overloaded 'fct(int&, char&)' is ambiguous
     fct(n,c);
            ^
test.cpp:19:12: note: candidates are:
test.cpp:3:6: note: void fct(int, double)
 void fct(int, double); // fonction III
      ^
test.cpp:4:6: note: void fct(double, int)
 void fct(double, int); // fonction IV
      ^
\end{lstlisting}

Si une seule fonction à deux arguments avait été définie, par exemple la fonction IV, le compilateur aurait été assez intelligent pour caster de lui-même les arguments. Cependant, nous n'avons aucune garantie de l'ordre d'évaluation des paramètres de la fonction. C'est-à-dire que le compilateur aurait très bien pu faire ce cast (\texttt{int}$\rightarrow$\texttt{float}, \texttt{char}$\rightarrow$\texttt{int}) ou (\texttt{int}$\rightarrow$\texttt{int}, \texttt{char}$\rightarrow$\texttt{float}), la compilation aurait alors fonctionnée mais aucune garantie sur le résultat.\\
Pour plus d'explications détaillées, \href{http://www.cplusplus.com/doc/tutorial/typecasting/}{Type conversions [cplusplus.com]}\\

h. \texttt{fct(n,z)} $\rightarrow$ correcte, appel à la fonction III.\\

i. \texttt{fct(z,z,z)} $\rightarrow$ incorrecte. Problème avec le nombre d'arguments, c'est beaucoup plus évident qu'avec la proposition g.
\begin{lstlisting}[style=ShellStyle]
test.cpp:22:14: error: no matching function for call to 'fct(double&, double&, double&)'
     fct(z,z,z);
              ^
test.cpp:22:14: note: candidates are:
test.cpp:1:5: note: int fct(int)
 int fct(int); // fonction I
     ^
test.cpp:1:5: note:   candidate expects 1 argument, 3 provided
test.cpp:2:5: note: int fct(double)
 int fct(double); // fonction II
     ^
test.cpp:2:5: note:   candidate expects 1 argument, 3 provided
test.cpp:3:6: note: void fct(int, double)
 void fct(int, double); // fonction III
      ^
test.cpp:3:6: note:   candidate expects 2 arguments, 3 provided
test.cpp:4:6: note: void fct(double, int)
 void fct(double, int); // fonction IV
      ^
test.cpp:4:6: note:   candidate expects 2 arguments, 3 provided
\end{lstlisting}

\subsection*{Question 2}
\addcontentsline{toc}{subsection}{Question 2}

\begin{minted}[linenos=true,frame=single,fontsize=\scriptsize]{c++}
  int F(void); // renvoie toujours 1
  int F(double d); // renvoie 0 si d>0 sinon 1 
  
  int F(void) {
    return 1;
  }

  int F(double d) {
    return (d > 0.0) ? 0 : 1; // <= intruction ternaire, equivalent a un if ... else ... 
  }
\end{minted}

\subsection*{Question 3}
\addcontentsline{toc}{subsection}{Question 3}

i) \texttt{n} aura la même valeur avant et après, il aurait fallu utiliser un pointeur ou une référence pour modifier la valeur de n. Les arguments passés à une fonction sont copiés avant l'entrée dans celle-ci, toutes modifications apportées à ces arguments ne sont effectives qu'à l'intérieur de cette fonction à l'exception des pointeurs et des références.
\begin{lstlisting}[style=ShellStyle]
Avant, n = 12
Apres, n = 12
\end{lstlisting}

ii) Solution avec les pointeurs :
\begin{minted}[linenos=true,frame=single,fontsize=\scriptsize]{c++}
#include <iostream>
using namespace std;

void ajoute(int exp, int* var) {
  *var += exp;
}

int main(void) {
  int n = 12;
  int p = 3;
  cout << "Avant, n = " << n << "\n";
  ajoute(2*p+1, &n);
  cout << "Apres, n = " << n << "\n";
  return 0;
}
\end{minted}

iii) Oui, il existe plusieurs manières. En programmation, il n'existe pas une seule solution mais toujours des solutions !\\
Dans la solution précédente, on a utilisé les pointeurs mais on peut aussi utiliser les références.
\begin{minted}[linenos=true,frame=single,fontsize=\scriptsize]{c++}
#include <iostream>
using namespace std;

void ajoute(int exp, int& var) {
  var += exp;
}

int main(void) {
  int n = 12;
  int& ref_n = n;
  int p = 3;
  cout << "Avant, n = " << n << "\n";
  ajoute(2*p+1, ref_n);
  cout << "Apres, n = " << n << "\n";
  return 0;
}
\end{minted}

\section*{Constructeurs et destructeurs}
\addcontentsline{toc}{section}{Constructeurs et destructeurs}

\subsection*{Question de cours}
\addcontentsline{toc}{subsection}{Question de cours}

\subsubsection*{Le contructeur}
\addcontentsline{toc}{subsubsection}{Le contructeur}

Le contructeur est pour un utilisateur d'une classe une méthode particulière permettant de créer un objet initialisé.\\

En C++, il est possible de surcharger les constructeurs, c’est-à-dire créer des constructeurs ayant le même nom mais avec des paramètres de types différents et/ou un nombre de paramètres différents. Chaque constructeur ou fonction surchargé se différencie de son homonyme par le nombre et le type des paramètres passés et renvoyés.\\

Il existe deux constructeurs particuliers :
\begin{itemize}
\item le constructeur par défaut qui n’a aucun argument ;
\item le constructeur par copie qui a un unique argument du même type que l’objet à créer (généralement sous forme de référence constante $\rightarrow$ \texttt{const Type\_Objet \&}) et qui recopie les attributs de l’objet passé en argument dans l’objet à créer.
\end{itemize}

\subsubsection*{Le destructeur}
\addcontentsline{toc}{subsubsection}{Le destructeur}

Le destructeur d'un objet est une méthode particulière d'une classe qui sera appelée à chaque fois qu'un objet de cette classe sera détruit automatiquement (géré par le compilateur) ou dynamiquement (\texttt{delete ...;}).\\
En général, il sert à désallouer la mémoire des attributs de l'objet qui ont été alloués dynamiquement.

\subsection*{Déclaration d'une classe de base}
\addcontentsline{toc}{subsection}{Déclaration d'une classe de base}

\subsubsection*{vecteur3d.hpp}
\inputminted[linenos=true,frame=single,fontsize=\scriptsize]{c++}{../src/vecteur3d.hpp}

\subsubsection*{vecteur3d.cpp}
\inputminted[linenos=true,frame=single,fontsize=\scriptsize]{c++}{../src/vecteur3d.cpp}

\section*{Const correctness}
\addcontentsline{toc}{section}{Const correctness}

\begin{minted}[linenos=false,frame=none,fontsize=\scriptsize]{c++}
    void f(const int &i);
\end{minted}
fonction prenant en paramètre une référence sur un entier constant. La valeur de la référence pourra changer mais il sera impossible de modifier la valeur de la variable entière référencée.\\

\begin{minted}[linenos=false,frame=none,fontsize=\scriptsize]{c++}
    double const g = 5;
\end{minted}
déclaration d'un nombre flottant constant qui a pour valeur 5.\\

\begin{minted}[linenos=false,frame=none,fontsize=\scriptsize]{c++}
    double* const h = NULL;
\end{minted}
déclaration d'un pointeur constant sur un flottant : la valeur de ce pointeur ne peut être modifiée, il pointera toujours sur \texttt{NULL}.\\

\begin{minted}[linenos=false,frame=none,fontsize=\scriptsize]{c++}
    int unecertaineclasse::f2(const int i) const;
\end{minted}
méthode de la classe \texttt{unecertaineclasse} qui prend en paramètre un entier constant et qui est définie comme constante, c'est-à-dire qu'elle n'apportera aucune modification à l'objet durant son exécution.\\

Le point le plus épineux de cette question est le sens de la déclaration selon l'emplacement du \texttt{const}. Voici un article qui parle de la déclaration avec \texttt{const} et des différents cas d'utilisation :\\
\href{http://duramecho.com/ComputerInformation/WhyHowCppConst.html}{The C++ 'const' Declaration: Why \& How}\\

Voici la partie concernant les déclarations : (non traduite par peur d'introduire un contre-sens :P)\\

\begin{center}
\begin{minipage}[c]{0.85\textwidth}
  \textbf{Simple Use of ‘const’}\\

  The simplest use is to declare a named constant. This was available in the ancestor of C++, C.\\
  To do this, one declares a constant as if it was a variable but add ‘const’ before it. One has to initialise it immediately in the constructor because, of course, one cannot set the value later as that would be altering it.
\end{minipage}

\begin{minipage}[c]{0.85\textwidth}
  For example,
  \begin{minted}[linenos=false,frame=none,fontsize=\scriptsize]{c++}
    const int Constant1=96;
  \end{minted}
  will create an integer constant, unimaginatively called \texttt{Constant1}, with the value 96.\\
  
  Such constants are useful for parameters which are used in the program but are do not need to be changed after the program is compiled. It has an advantage for programmers over the C preprocessor \texttt{\#define} command in that it is understood \& used by the compiler itself, not just substituted into the program text by the preprocessor before reaching the main compiler, so error messages are much more helpful.\\
  
  It also works with pointers but one has to be careful where \texttt{const} is put as that determines whether the pointer or what it points to is constant. For example,
  \begin{minted}[linenos=false,frame=none,fontsize=\scriptsize]{c++}
    const int * Constant2
  \end{minted}
  declares that \texttt{Constant2} is a variable pointer to a constant integer and
  \begin{minted}[linenos=false,frame=none,fontsize=\scriptsize]{c++}
    int const * Constant2
  \end{minted}
  is an alternative syntax which does the same, whereas
  \begin{minted}[linenos=false,frame=none,fontsize=\scriptsize]{c++}
    int * const Constant3
  \end{minted}
  declares that \texttt{Constant3} is constant pointer to a variable integer and
  \begin{minted}[linenos=false,frame=none,fontsize=\scriptsize]{c++}
    int const * const Constant4
  \end{minted}
  declares that \texttt{Constant4} is constant pointer to a constant integer.\\

  \textbf{/!\textbackslash  RULE : Basically \texttt{const} applies to whatever is on its immediate left (other than if there is nothing there in which case it applies to whatever is its immediate right).}
\end{minipage}
\end{center}

\section*{Héritage et polymorphisme}
\addcontentsline{toc}{section}{Héritage et polymorphisme}

\subsection*{Questions de cours}
\addcontentsline{toc}{subsection}{Questions de cours}

\subsubsection*{L'héritage}
\addcontentsline{toc}{subsubsection}{L'héritage}

L'héritage est un concept de la programmation orientée objet qui permet entre aures la réutilisabilité (décomposition du système en composants) et l'adaptabilité des objets grâce au polymorphisme. Ce concept est en quelque sorte le même que celui d'un arbre généalogique. Les classes ``filles'' héritent des caractéristiques de leur(s) mère(s) mais tous les attributs de la classe ``mère'' ne sont pas forcément accessibles depuis les classes ``filles'', cela dépend de la portée de l'héritage (\texttt{private}, \texttt{protected}, \texttt{public}). \cite{wikipedia-heritage}

\subsubsection*{Différence entre l'héritage et la composition}
\addcontentsline{toc}{subsubsection}{Différence entre l'héritage et la composition}

Comme déjà dit précédemment, le concept d'héritage est le même que celui d'un arbre généalogique.\\
Le concept de composition est le même que celui d'une horloge ou d'une machine complexe composée de plein de petites pièces. Prenons l'exemple d'une voiture. Elle possède un moteur, 4 roues, un volant, etc... Si vous enlevez un de ces éléments, votre voiture n'est plus une voiture car elle n'est plus capable de fonctionner normalement et d'assumer sa principalement fonction.\\

Un exemple clair est disponible sur \href{http://en.wikipedia.org/wiki/Object_composition#UML_notation}{Wikipédia; Object composition,UML notation}.

\subsection*{Application}
\addcontentsline{toc}{subsection}{Application}

Programme :
\begin{minted}[linenos=true,frame=single,fontsize=\scriptsize]{c++}
  int main(void) {
    
    classeA var1;
    classeB var2(5,8);
    classeC var3;
    classeA var4 = &var1;
    return 0;
  }
\end{minted}

\subsubsection*{Quelques rappels}
\addcontentsline{toc}{subsubsection}{Quelques rappels}

La construction d'un objet commence toujours en partant de la classe ``mère''. Si il y a plusieurs classes ``mère'', alors la construction commence par la classe la plus à gauche (ordre de déclaration d'héritage lors de la déclaration de la classe \texttt{class MaClasse : ClasseMere1, ClasseMere2, ... \{ ... \}}).\\
Ensuite vient le tour des attributs. Ils sont initialisés dans l'ordre où ils ont été déclarés.\\
Pour finir, la classe elle-même est construite.\\

L'ordre des destructeurs est exactement dans le sens inverse.

\subsubsection*{Construction}
\addcontentsline{toc}{subsubsection}{Construction}

\underline{Affichage :}\\

création d'un objet de classe A :
\begin{lstlisting}[style=ShellStyle]
Constructeur de la classe A
\end{lstlisting}

\vspace{3mm}

création d'un objet de classe B qui a nécessité la création d'un objet de classe A\\$\rightarrow$ 2 possibilités : composition ou héritage ?\\
\textit{Si on suppose que les constructeurs affichent leur message à la fin de la construction de l'objet, allors il s'agit d'héritage ou de composition.\\
Si on suppose que les constructeurs affichent leur message dès qu'on rentre dans le constructeur, alors on est certain qu'il s'agit d'héritage car on aurait eu l'affichage inverse s'il s'agissait de composition.}
\begin{lstlisting}[style=ShellStyle]
Constructeur de la classe A
Constructeur de la classe B
\end{lstlisting}

\vspace{3mm}

création d'un objet de classe C qui a nécessité la création d'un objet de classe A\\$\rightarrow$ 2 possibilités : composition ou héritage ?\\
\textit{Même problème qu'auparavant}
\begin{lstlisting}[style=ShellStyle]
Constructeur de la classe A
Constructeur de la classe C
\end{lstlisting}

\vspace{3mm}

\textit{L'exercice nous dit qu'il faut proposer deux diagrammes possibles, on prendra donc l'hypothèse que les constructeurs affichent leur message à la fin de la construction de l'objet pour tomber dans le cas où il y a confusion ;-)}\\

Voici les quatre diagrammes de classe possibles :
\begin{center}
  \includegraphics[scale=0.40,angle=-90]{diagramme-de-classes.pdf}
\end{center}

\subsubsection*{Destruction}
\addcontentsline{toc}{subsubsection}{Destruction}

\underline{Affichage :}\\

Destruction de l'objet de la classe C puis destruction de l'objet de la classe A.
\begin{lstlisting}[style=ShellStyle]
Destructeur de la classe C
Destructeur de la classe A
\end{lstlisting}

\vspace{3mm}

Destruction de l'objet de la classe B puis destruction de l'objet de la classe A.
\begin{lstlisting}[style=ShellStyle]
Destructeur de la classe B
Destructeur de la classe A
\end{lstlisting}

\vspace{3mm}

Destruction de l'objet de la classe A.
\begin{lstlisting}[style=ShellStyle]
Destructeur de la classe A
\end{lstlisting}

\vspace{3mm}

L'ordre des destructeurs dans le cas de l'héritage est exactement dans le sens inverse l'inverse de la construction. L'ordre des destructeurs n'invalide pas les diagrammes de classes proposé.\\

L'ordre des destructeurs dans le cas de la composition est aussi dans le sens inverse l'inverse de la construction. On rentre d'abord dans le destructeur puis on détruit les attributs. Cependant, les diagrammes de classes proposés avec le cas de la composition ne sont valides que si l'affichage se fait directement à l'entrée dans le destructeur sinon il n'y a qu'un seul diagramme de classes possible, celui avec l'héritage.


\begin{thebibliography}{99}
\bibitem[WikHer]{wikipedia-heritage}
Wikipédia, l'\href{http://fr.wikipedia.org/wiki/Héritage_(informatique)}{héritage}
\end{thebibliography}

\end{document}

